package com.paltform.qiniu.service;

import com.alibaba.fastjson.JSON;
import com.paltform.qiniu.model.FileModel;
import com.platform.base.common.dto.Result;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.BatchStatus;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.qiniu.util.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Service
public class QiniuServiceImpl implements IQiniuService {

    @Value("${config.qiniu.accessKey}")
    private String ak;

    @Value("${config.qiniu.secretKey}")
    private String sk;

    @Value("${config.qiniu.bucket}")
    private String bucket;

    @Value("${config.qiniu.zone}")
    private String zoneConfig;

    private Zone getZone() {
        switch(zoneConfig){
            case "zone1" :
                return Zone.zone1();
            case "zone2" :
                return Zone.zone2();
            default : //可选
                return Zone.zone0();
        }
    }

    private UploadManager createUploadManager() {
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(getZone());
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        return uploadManager;
    }

    private BucketManager createBucketManager() {
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(getZone());
        //...其他参数参考类注释
        Auth auth = Auth.create(ak, sk);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        return bucketManager;
    }

    @Override
    public String getUploadToken() {
        Auth auth = Auth.create(ak, sk);
        String upToken = auth.uploadToken(bucket);
        return upToken;
    }

    @Override
    public String getUploadToken(String fileKey) {
        Auth auth = Auth.create(ak, sk);
        String upToken = auth.uploadToken(bucket, fileKey);
        return upToken;
    }

    @Override
    public Result upLoadFile(MultipartFile file) throws IOException{
        return uploadFile(file.getInputStream(), null, "");
    }

    @Override
    public Result upLoadFileByInputStream(InputStream instreams) {
        return uploadFile(instreams, null, "");
    }

    @Override
    public Result upLoadImageByInputStream(InputStream instreams) {
        String mimeLimit = "image/png";
        //默认不指定key的情况下，以文件内容的hash值作为文件名
        String key = "aaaa.png";
        return uploadFile(instreams, key, mimeLimit);
    }

    private Result uploadFile(InputStream instreams, String key, String mime) {
        Result res = new Result();
        UploadManager uploadManager = createUploadManager();
        String upToken = getUploadToken();

        try {
            Response qiniuresponse = uploadManager.put(instreams, key, upToken, null, null);
            //解析上传成功的结果
            DefaultPutRet putRet = JSON.parseObject(qiniuresponse.bodyString(), DefaultPutRet.class);
            String rskey = putRet.hash;
            if(!StringUtils.isNullOrEmpty(rskey)){
                res.setSuccess(true);
                res.setMessage("上传成功");
                res.setData(rskey);
            }
        } catch (QiniuException ex) {
            res.setSuccess(false);
            res.setMessage("上传失败");
            ex.printStackTrace();
        } catch (IOException e) {
            res.setSuccess(false);
            res.setMessage("上传失败");
            e.printStackTrace();
        }
        return res;
    }

    @Override
    public Result getFileInfoByKey(String key) {
        Result res = new Result();
        BucketManager bucketManager = createBucketManager();
        try {
            FileInfo fileInfo = bucketManager.stat(bucket, key);
            res.setSuccess(true);
            res.setMessage("获取成功");
            res.setData(fileInfo);
        } catch (QiniuException ex) {
            res.setSuccess(false);
            res.setMessage("获取失败");
            ex.printStackTrace();
        }
        return res;
    }

    @Override
    public Result deleteFileByKey(String key) {
        Result res = new Result();
        BucketManager bucketManager = createBucketManager();
        try {
            Response response = bucketManager.delete(bucket, key);
            if(response.statusCode == 200) {
                res.setSuccess(true);
                res.setMessage("删除成功");
            }else{
                res.setSuccess(false);
                res.setMessage("删除失败");
            }
        } catch (QiniuException ex) {
            res.setSuccess(false);
            res.setMessage("删除失败");
            //如果遇到异常，说明删除失败
            ex.printStackTrace();
        }
        return res;
    }

    @Override
    public Result setFileExpireTime(String key, int days) {
        Result res = new Result();
        BucketManager bucketManager = createBucketManager();
        try {
            Response  response = bucketManager.deleteAfterDays(bucket, key, days);
            if(response.statusCode == 200){
                res.setSuccess(true);
                res.setMessage("设置成功");
            }else{
                res.setSuccess(false);
                res.setMessage("设置失败");
            }
        } catch (QiniuException ex) {
            res.setSuccess(false);
            res.setMessage("设置失败");
            ex.printStackTrace();
        }
        return res;
    }

    @Override
    public Result getFileListInfo(String prefix, String delimiter) {
        Result res = new Result();
        BucketManager bucketManager = createBucketManager();
        //每次迭代的长度限制，最大1000，推荐值 1000
        int limit = 1000;

        //列举空间文件列表
        BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(bucket, prefix, limit, delimiter);
        List<FileModel> fileList = new ArrayList<>();
        while (fileListIterator.hasNext()) {
            //处理获取的file list结果
            FileInfo[] items = fileListIterator.next();
            for (FileInfo item : items) {
                FileModel model = new FileModel();
                model.setKey(item.key);
                model.setHash(item.hash);
                model.setSize(item.fsize);
                model.setType(item.mimeType);
                model.setPutTime(item.putTime);
                model.setEndUser(item.endUser);
                fileList.add(model);
            }
        }
        res.setSuccess(true);
        res.setMessage("获取成功");
        res.setData(fileList);
        return res;
    }

    @Override
    public Result deleteBatchFile(String[] keyList) {
        if(keyList.length > 1000){
            throw new RuntimeException("批量删除文件个数不能超过1000");
        }
        Result res = new Result();
        if(keyList.length == 0){
            res.setSuccess(false);
            res.setMessage("删除文件不能为空");
            return res;
        }
        BucketManager bucketManager = createBucketManager();
        try {
            BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
            batchOperations.addDeleteOp(bucket, keyList);
            Response response = bucketManager.batch(batchOperations);
            BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
            res.setSuccess(true);
            res.setMessage("删除文件成功");
            res.setData(batchStatusList);
        } catch (QiniuException ex) {
            res.setSuccess(false);
            res.setMessage("删除文件失败");
            ex.printStackTrace();
        }
        return res;
    }
}
